package br.poli.ecomp.sma.massim.action;

import jason.asSemantics.DefaultInternalAction;
import jason.asSemantics.TransitionSystem;
import jason.asSemantics.Unifier;
import jason.asSyntax.NumberTerm;
import jason.asSyntax.NumberTermImpl;
import jason.asSyntax.Term;
import jason.environment.grid.Location;

import java.util.Random;
import java.util.logging.Level;

import br.poli.ecomp.sma.massim.arch.EcompArch;
import br.poli.ecomp.sma.massim.env.Search;
import br.poli.ecomp.sma.massim.env.WorldModel;
import busca.Nodo;

public class FindPos2 extends DefaultInternalAction {

	private static final long serialVersionUID = 1L;
	WorldModel.Move[] actionsOrder = new WorldModel.Move[WorldModel.nbActions];
    Random     random = new Random();

	@Override
	public Object execute(TransitionSystem ts, Unifier un, Term[] terms)
			throws Exception {
//
		Term tx = terms[0];
		Term ty = terms[1];
		Term newX = terms[4];
		Term newY = terms[5];
//
		int x = (int) ((NumberTerm) tx).solve();
		int y = (int) ((NumberTerm) ty).solve();
		
		try {
            WorldModel.Move m = WorldModel.Move.skip;
            Nodo solution = findPath(ts, terms);
            
            if (solution != null) {
                m = Search.firstAction(solution);
            } else {
                ts.getLogger().info("No route from "+ terms[0]+","+terms[1] +" to "+ terms[2]+","+terms[3]+"!");
            }
            
            Location newL = WorldModel.getNewLocationForAction(new Location(x, y), m);
            un.unifies(newX, new NumberTermImpl(newL.x));
    		un.unifies(newY, new NumberTermImpl(newL.y));
        
		} catch (Throwable e) {
            ts.getLogger().log(Level.SEVERE, "direction error: "+e, e);    		
        }
        return false;
	}
	
	 protected Nodo findPath(TransitionSystem ts, Term[] terms) throws Exception {

		EcompArch arch = (EcompArch) ts.getUserAgArch();
		WorldModel model = arch.getModel();

		Nodo solution = null;

		int iagx = (int) ((NumberTerm) terms[0]).solve();
		int iagy = (int) ((NumberTerm) terms[1]).solve();
		int itox = (int) ((NumberTerm) terms[2]).solve();
		int itoy = (int) ((NumberTerm) terms[3]).solve();
	    
		if (model.inGrid(itox,itoy)) {
			while (!model.isFreeOfObstacle(itox,itoy) && itox > 0) itox--;
            while (!model.isFreeOfObstacle(itox,itoy) && itox < model.getWidth()) itox++;
            Location from = new Location(iagx, iagy);
            Location to   = new Location(itox, itoy);
            
            Search astar    = new Search(model, from, to, null, arch);
            solution = astar.search();
		}
		
		return solution;
	 }
}
